package com.example.hao.togglebutton.View;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.example.hao.togglebutton.R;


public class ToggleButtonPlus extends View {

    /**
     * 开关的默认宽度
     */
    private static final int DEFAULT_WIDTH = 400;
    /**
     * 开关的默认高度为宽度的1半
     */
    private static final int DEFAULT_HEIGHT = (int) (DEFAULT_WIDTH / 2.5f);

    private boolean toggle;

    public boolean isToggle() {
        return toggle;
    }

    public void setToggle(boolean toggle) {
        this.toggle = toggle;
        buttonLeft = toggle ? maxDistance : 0;
        invalidate();
    }

    private Bitmap background;

    private Bitmap button;

    public ToggleButtonPlus(Context context) {
        super(context);
    }

    public ToggleButtonPlus(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
        initBitmap();
    }

    private Rect backgroundRect;
    private Rect buttonRect;


    private void initBitmap() {
        background = BitmapFactory.decodeResource(getResources(), R.mipmap.switch_background);
        button = BitmapFactory.decodeResource(getResources(), R.mipmap.slide_button);

        backgroundRect = new Rect(0, 0, background.getWidth(), background.getHeight());
        buttonRect = new Rect(0, 0, button.getWidth(), button.getHeight());

    }


    private void init(AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ToggleButtonPlus);
        toggle = typedArray.getBoolean(R.styleable.ToggleButtonPlus_toggle, false);
        typedArray.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int specModeWidth = MeasureSpec.getMode(widthMeasureSpec);//得到宽度的布局模式
        int specSizeWidth = MeasureSpec.getSize(widthMeasureSpec);//得到布局参数的宽度
        int resultWidth = specSizeWidth;
        switch (specModeWidth) {
            case MeasureSpec.EXACTLY:// 宽高的值是固定的时候,如:match_parent 或 "22dp"
                resultWidth = specSizeWidth;
                break;
            case MeasureSpec.AT_MOST:// 你的宽高的值 为 wrap_content 的时候
                resultWidth = DEFAULT_WIDTH;
                break;
        }
        int specModeHeight = MeasureSpec.getMode(heightMeasureSpec);//得到高度的布局模式
        int specSizeHeight = MeasureSpec.getSize(heightMeasureSpec);//得到布局参数的高度
        int resultHeight = specSizeHeight;
        switch (specModeHeight) {
            case MeasureSpec.EXACTLY:// 宽高的值是固定的时候,如:match_parent 或 "22dp"
                resultHeight = specSizeHeight;
                break;
            case MeasureSpec.AT_MOST:// 你的宽高的值 为 wrap_content 的时候
                resultHeight = DEFAULT_HEIGHT;
                break;
        }
        //调用该方法,最终确定该View的宽高
        setMeasuredDimension(resultWidth, resultHeight);
        buttonWidth = getMeasuredWidth() / 1.8f;
        maxDistance = getMeasuredWidth() - buttonWidth;
        buttonLeft = toggle ? maxDistance : 0;
    }

    private float maxDistance;//计算 按钮最大滑动的距离

    private float buttonWidth;

    private float buttonLeft = 0;//改变 button 的Left位置.就可以实现按钮的滑动


    RectF drawBackRect = new RectF();
    RectF drawButtonRect = new RectF();

    @Override
    protected void onDraw(Canvas canvas) {
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        drawBackRect.set(0, 0, width, height);
        canvas.drawBitmap(background, backgroundRect, drawBackRect, null);

        drawButtonRect.set(buttonLeft, 0, buttonLeft + buttonWidth, height);
        canvas.drawBitmap(button, buttonRect, drawButtonRect, null);
    }

    private float x;
    private float y;


    private float lastX;
    private float lastY;


    private boolean isScroll;

    /**
     * 触摸
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        lastX = x;
        lastY = y;
        x = event.getX();
        y = event.getY();
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                isScroll = false;
                Log.d("TAG", "onTouchEvent: 按下" + x + "," + y);
                break;
            case MotionEvent.ACTION_MOVE:
                isScroll = true;
//                Log.d("TAG", "onTouchEvent: 滑动" + x + "," + y);
                float xDistance = Math.abs(lastX - x);
                float yDistance = Math.abs(lastY - y);
                if (xDistance > yDistance) {
                    //左右方向
                    if (lastX < x) {
                        Log.d("", "onTouchEvent: 向右");
                    } else {
                        Log.d("", "onTouchEvent: 向左");
                    }

                    buttonLeft += (x - lastX);
                    buttonLeft = buttonLeft <= 0 ? 0 : buttonLeft;
                    buttonLeft = buttonLeft >= maxDistance ? maxDistance : buttonLeft;
                } else {
                    //上下方向
                    if (lastY < y) {
                        Log.d("", "onTouchEvent: 向下");
                    } else {
                        Log.d("", "onTouchEvent: 向上");
                    }
                }
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                if (!isScroll) {
                    buttonLeft = buttonLeft == 0 ? maxDistance : 0;
                } else {
                    Log.d("TAG", "onTouchEvent: 抬起" + x + "," + y);
                    if (buttonLeft > maxDistance / 2) {
                        buttonLeft = maxDistance;
                    } else {
                        buttonLeft = 0;
                    }
                }
                invalidate();
                toggle = buttonLeft != 0;
                if (listener != null) {
                    listener.onToggle(toggle);
                }
                break;
        }
        return true;
    }

    private OnToggleListener listener;

    public void setOnToggleListener(OnToggleListener listener) {
        this.listener = listener;
    }

    public interface OnToggleListener {
        void onToggle(boolean toggle);
    }
}
